package com.ecloud.hbase.standard;

import com.ecloud.common.exception.InnerException;
import com.ecloud.hbase.util.HbaseUtil;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * HbaseTable实体接口
 *
 * @author Squbi
 * @date 2021/6/18 15:52
 */
public interface HbaseTable {
    /**
     * toTableMap 实体转为Map
     *
     * @return 可直接解析的map
     * @author Squbi
     * @date 2021/6/18 15:52
     */
    default Map<String, Map<String, String>> toTableMap() {
        Map<String, Map<String, String>> map = new HashMap<>();
        Class<? extends HbaseTable> clazz = this.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Map<String, String> m = (Map<String, String>) field.get(this);
                map.put(field.getName(), m);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new InnerException(" 错误定义的Table 其属性必须为 Map<String, String>");
            }
        }
        return map;
    }

    /**
     * 将result转化为实体
     *
     * @param result result
     * @author Squbi
     * @date 2021/6/18 15:53
     */
    default void parseResult(Result result) {
        Class<? extends HbaseTable> clazz = this.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                field.set(this, HbaseUtil.resultToMap(result, field.getName()));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new InnerException(" 错误定义的Table 其属性必须为存在的字段名");
            }
        }
    }

    /**
     * to Put.
     *
     * @param put Put
     * @return {@link Put}
     * @author sheldon
     * @date 2021/7/22 下午4:35
     */
    default Put toPut(Put put) {
        Map<String, Map<String, String>> map = this.toTableMap();
        for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
            Map<String, String> family = entry.getValue();
            for (Map.Entry<String, String> familyEntry : family.entrySet()) {
                put.addColumn(Bytes.toBytes(entry.getKey()), Bytes.toBytes(familyEntry.getKey()), Bytes.toBytes(familyEntry.getValue()));
            }
        }
        return put;
    }
}
